package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrdersMapper;
import com.itheima.reggie.mapper.ShoppingCartMapper;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author ：sean
 * @date ：Created in 2022/4/21
 * @description ：
 * @version: 1.0
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Override
    @Transactional
    public void submit(Orders orders) {
        /**
         * 1:找到所有 orders数据  存到数据库中
         * 2:把购物项信息转换成 订单信息 存到数据库中
         * 3:把购物项信息删除...
         *    问以上三个操作 是不是会涉及到很多表的操作
         *    所以 针对这种情况建议  service写一个单独色方法去处理
         */
        //1:找到所有 orders数据  存到数据库中
        /*
            丰富 咱们orders 所有数据
             查看有什么数据
             缺什么数据
         */
        //1.1 查看 有什么数据
        // 地址簿id
        Long addressBookId = orders.getAddressBookId();
        // 备注
        String remark = orders.getRemark();
        // 支付方式
        Integer payMethod = orders.getPayMethod();
        // 1.2 缺什么  根据已知条件能不能找到缺失内容
        // 解决跟地址相关的数据 因为知道地址簿 就可找到地址相关数据
        AddressBook addressBook = addressBookService.getById(addressBookId);
        // addressBook里面 就搞定了 phone address consignee
        // user_name 找谁搞定 user_id 找谁搞定?
        //  谁登录 就根据谁查询
        //先获取用户id 登录的用户
        Long userId = BaseContext.getCurrentId();
        User user = userService.getById(userId);
        // user user_name user_id
        // 订单号
//         用uuid完成
//         String number = UUID.randomUUID().toString().replace("-", "");
//        String number = IdWorker.get32UUID(); 32位uuid
          String number = IdWorker.getId()+"";// 雪花算法19位
        // 下单时间 支付时间
        LocalDateTime now = LocalDateTime.now();

        // 上面是不是把 除了 amount以外的所有数据都列出来了 还没设置
        // 1.3 把缺的补上
        // 订单号
        orders.setNumber(number);
        // 用户id  用户名字
        orders.setUserId(userId);
        orders.setUserName(user.getName());// 没有名字不用做这一步...
        // 地址簿相关信息
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());//按照标准 地址 省市区级联  加 详细地址
        // 下单和 结算时间
        orders.setOrderTime(now);
        orders.setCheckoutTime(now);


        // 当前订单金额--- 跟订单明细相关......!!!!!!!! 需要计算  这一种算法....
       /*

         订单总金额 = 每个订单详情(购物项)的单价*数量 进行累加
        */
        log.info("开始计算总金额");
        // 定义累加的总金额数据  初始值是0
        BigDecimal amount = new BigDecimal(0);
//        double sum = 0;
         // 总金额的获取 就 结合 购物项和订单转换了....
        //2:把购物项信息转换成 订单信息 存到数据库中
        // 2.1 查询 当前用户的 指定的所有的购物项信息
        LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShoppingCart::getUserId,userId);// where user_id=?
        //  select *  from shopping_cart where user_id=用户id
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);

        log.info("同时开始进行购物项和订单明细转换");
        // shoppingCarts 是该用户的所有购物项信息
        // 把所有的购物项 全部变成 所有的订单(明细)项集合
        List<OrderDetail> orderDetails = new ArrayList<>();
        //  List<ShoppingCart>  ===>  List<OrderDetail>
        // 遍历里面转换每一个
        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            // shoppingCart orderDetail
            // orderDetail   除了订单id        shoppingCart里面都有
            BeanUtils.copyProperties(shoppingCart,orderDetail,"id");
            // 因为没有订单id 设置订单id
            orderDetail.setOrderId(Long.parseLong(number));

            orderDetails.add(orderDetail);

            // 计算总金额
            // 单价 和 份数
            BigDecimal danjia = shoppingCart.getAmount();
            BigDecimal fenshu = new BigDecimal(shoppingCart.getNumber());
            // 计算小计
            BigDecimal xiaoji = danjia.multiply(fenshu);
            // 小计 =单价*份数
            // sum = sum+小计
            amount = amount.add(xiaoji);

        }
        // 循坏外面进行设置
        orders.setAmount(amount);

        // 得到了有数据的  orderDetails集合 保存
         // 保存两个数据
           //orders数据
         this.save(orders);
           //orderDetails集合
         orderDetailService.saveBatch(orderDetails);

        // 3:清空购物车  是不是写过这个功能
        log.info("3:清空该用户的所有购物项");


        // delete  from shopping_cart where user_id=用户id

        shoppingCartService.remove(wrapper);

    }
}
